﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace g4
{
    public class IntrLine3Line3
    {
        private Line3d _line1;
        private Line3d _line2;
        public IntersectionResult Result { get; set; } = IntersectionResult.NotComputed;
        public IntersectionType Type { get; set; } = IntersectionType.Empty;
        public Vector3d IntersectDot { get; set; }

        public IntrLine3Line3(Line3d line1, Line3d line2)
        {
            _line1 = line1;
            _line2 = line2;
        }

        public IntrLine3Line3 Compute()
        {
            Find();
            return this;
        }

        public bool Find()
        {
            if (Result != IntersectionResult.NotComputed)
                return (Result == IntersectionResult.Intersects);

            Vector3d a = _line1.Origin;
            Vector3d b = _line1.Origin + _line1.Direction;
            Vector3d c = _line2.Origin;
            Vector3d d = _line2.Origin + _line2.Direction;

            Vector3d ab = b - a;
            Vector3d ca = a - c;
            Vector3d cd = d - c;

            Vector3d v1 = Vector3d.Cross(ca, cd);

            if (Math.Abs(Vector3d.Dot(v1, ab)) > 1e-6)
            {
                Result = IntersectionResult.NoIntersection;
                // 不共面
                return false;
            }

            if (Vector3d.Cross(ab, cd).sqrMagnitude <= 1e-6)
            {
                Result = IntersectionResult.NoIntersection;
                // 平行
                return false;
            }

            Vector3d ad = d - a;
            Vector3d cb = b - c;

            Vector3d v2 = Vector3d.Cross(cd, ab);
            double ratio = Vector3d.Dot(v1, v2) / v2.sqrMagnitude;
            IntersectDot = a + ab * ratio;

            Result = IntersectionResult.Intersects;
            Type = IntersectionType.Point;
            return true;

        }
    }
}
